package com.xsq.wifi.utils;

/**
 * 编写人：李振德
 * 创建时间：2025/5/9
 */
import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.util.Log;
import java.io.IOException;
import java.net.*;

public class SSDPScanner {
    private static final String TAG = "SSDPScanner";
    private static final String SSDP_IP = "239.255.255.250";
    private static final int SSDP_PORT = 1900;
    private static final String SEARCH_MESSAGE =
            "M-SEARCH * HTTP/1.1\r\n" +
                    "HOST: 239.255.255.250:1900\r\n" +
                    "MAN: \"ssdp:discover\"\r\n" +
                    "MX: 2\r\n" +
                    "ST: upnp:rootdevice\r\n\r\n";

    private final Context context;
    private MulticastLock multicastLock;
    private volatile boolean isDiscovering = false;

    public SSDPScanner(Context context) {
        this.context = context;
    }

    public void startDiscovery(final OnDeviceFoundListener listener) {
        if (isDiscovering) {
            listener.onError(new IllegalStateException("Discovery already in progress"));
            return;
        }

        isDiscovering = true;
        new Thread(() -> {
            try {
                // 获取组播锁
                WifiManager wifi = (WifiManager) context.getApplicationContext()
                        .getSystemService(Context.WIFI_SERVICE);
                multicastLock = wifi.createMulticastLock("SSDP_Lock");
                multicastLock.setReferenceCounted(true);
                multicastLock.acquire();

                DatagramSocket socket = new DatagramSocket();
                socket.setReuseAddress(true);
                socket.setSoTimeout(5000); // 5秒超时

                // 发送搜索请求
                InetAddress group = InetAddress.getByName(SSDP_IP);
                DatagramPacket searchPacket = new DatagramPacket(
                        SEARCH_MESSAGE.getBytes(),
                        SEARCH_MESSAGE.getBytes().length,
                        group,
                        SSDP_PORT
                );
                socket.send(searchPacket);

                // 接收响应
                boolean hasDevices = false;
                long endTime = System.currentTimeMillis() + 5000; // 总扫描时间5秒

                while (System.currentTimeMillis() < endTime) {
                    try {
                        byte[] buffer = new byte[1024];
                        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                        socket.receive(packet);

                        String response = new String(packet.getData(), 0, packet.getLength());
                        String deviceIp = packet.getAddress().getHostAddress();
                        String deviceUrl = parseLocationHeader(response);

                        hasDevices = true;
                        if (listener != null) {
                            listener.onDeviceFound(deviceIp, deviceUrl, response);
                        }
                    } catch (SocketTimeoutException e) {
                        // 单次接收超时，继续循环直到总扫描时间结束
                    }
                }

                // 扫描完成回调
                if (listener != null) {
                    listener.onDiscoveryFinished(hasDevices);
                }

            } catch (Exception e) {
                Log.e(TAG, "Discovery error", e);
                if (listener != null) {
                    listener.onError(e);
                }
            } finally {
                releaseMulticastLock();
                isDiscovering = false;
            }
        }).start();
    }

    public void stopDiscovery() {
        isDiscovering = false;
    }

    private String parseLocationHeader(String response) {
        String[] lines = response.split("\r\n");
        for (String line : lines) {
            if (line.toLowerCase().startsWith("location:")) {
                return line.substring("location:".length()).trim();
            }
        }
        return null;
    }

    private void releaseMulticastLock() {
        if (multicastLock != null && multicastLock.isHeld()) {
            multicastLock.release();
            multicastLock = null;
        }
    }

    public interface OnDeviceFoundListener {
        void onDeviceFound(String deviceIp, String deviceUrl, String rawResponse);
        void onDiscoveryFinished(boolean hasDevices);
        void onError(Exception e);
    }
}